﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace UtilZ.Dotnet.Ex.Base
{
    /// <summary>
    /// 可枚举的集合部分枚举器
    /// </summary>
    public class PartEnumerator<T> : IEnumerator<T>
    {
        private readonly IEnumerable<T> _items;
        private readonly int _startIndex;
        private readonly int _end;
        private int _index = -1;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="items">可枚举的集合</param>
        /// <param name="startIndex">集合中起始位置</param>
        /// <param name="count">枚举的项数</param>
        public PartEnumerator(IEnumerable<T> items, int startIndex, int count)
        {
            this._items = items;
            this._startIndex = startIndex;
            this._end = startIndex + count;
        }

        /// <summary>
        /// <see cref="IEnumerator{T}"/>
        /// </summary>
        public T Current
        {
            get
            {
                return this._items.ElementAt(this._index);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        object IEnumerator.Current
        {
            get
            {
                return this._items.ElementAt(this._index);
            }
        }


        /// <summary>
        /// 
        /// </summary>
        public void Dispose()
        {

        }

        /// <summary>
        /// 移动到下一个枚举项
        /// </summary>
        /// <returns></returns>
        public bool MoveNext()
        {
            this._index++;
            if (this._index < this._end)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 重置枚举器
        /// </summary>
        public void Reset()
        {
            this._index = this._startIndex - 1;
        }

    }


#pragma warning disable 8500
    /// <summary>
    /// 指针部分枚举器
    /// </summary>
    unsafe public class PointerEnumerator<T> : IEnumerator<T> where T : struct
    {
        private readonly T* _dataPtr;
        private readonly long _length;
        private long _index = -1;


        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="ptr">数据指针</param>
        /// <param name="count">枚举的项数</param>
        public PointerEnumerator(T* ptr, int count)
        {
            this._dataPtr = ptr;
            this._length = count;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="ptr">数据指针</param>
        /// <param name="count">枚举的项数</param>
        public PointerEnumerator(T* ptr, long count)
        {
            this._dataPtr = ptr;
            this._length = count;
        }


        /// <summary>
        /// <see cref="IEnumerator{T}"/>接口成员当前项
        /// </summary>
        public T Current
        {
            get
            {
                return this._dataPtr[this._index];
            }
        }

        /// <summary>
        /// 
        /// </summary>
        object IEnumerator.Current
        {
            get
            {
                return this._dataPtr[this._index];
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void Dispose()
        {

        }

        /// <summary>
        /// 移动到下一个枚举项
        /// </summary>
        /// <returns></returns>
        public bool MoveNext()
        {
            this._index++;
            if (this._index < this._length)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 重置枚举器
        /// </summary>
        public void Reset()
        {
            this._index = -1;
        }

    }
}
